//
//  SFOrderEncryService.m
//  SefonLockHelpr
//
//  Created by Kai Kang on 2019/1/20.
//  Copyright © 2019 Sefon Group. All rights reserved.
//

#import "SFOrderEncryService.h"

static SFOrderEncryService * _instance = nil;

//  记录每次传输数据的header
NSMutableArray * packetHeaderArr;
//  herder的长度
int packetHeaderLength;
// 不能在外界访问的常量定义
NSString * deviceType;

@interface SFOrderEncryService() {
    // 发送结束
    BOOL       isEnd;
}

@property (nonatomic, copy) NSMutableString * orderStr;

@end

@implementation SFOrderEncryService

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

+ (instancetype)sharedInstance {
    if (_instance == nil) {
        _instance = [[super alloc] init];
    }
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}

- (NSMutableString *)orderStr {
    if (!_orderStr) {
        _orderStr = [NSMutableString string];
    }
    return _orderStr;
}

- (void)appendOrderData:(NSData *)data {
    NSString * string = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
    if (string == nil) { return; }
    NSLog(@"receive order: %@", string);
    
    
    [self.orderStr appendString:string];
    
    // 保证长度大于3的时候才解析，因为3是
    if (self.orderStr.length >= 3) {
        // 一条命令长度
        NSInteger dataLength = [self.orderStr substringWithRange: NSMakeRange(0, 3)].integerValue;
        // 如果orderStr不是以数字（命令长度）开头的，就重置orderStr
        if (dataLength == 0) {
            self.orderStr = nil;
            [self.orderStr appendString:string];
        }
        // orderStr的长度大于等于命令的长度+3（表示前3位），表示一条命令发送完成
        if (dataLength > 0 && self.orderStr.length >= dataLength + 3) {
            // 命令内容
            self.orderStr = [[self.orderStr substringWithRange:NSMakeRange(3, dataLength)] mutableCopy];
            NSLog(@"whole order: %@", self.orderStr);
            [self autoReplay];
            [self encry];
            self.orderStr = nil;
        }
    }
}

- (void)autoReplay {
    if (self.delegate) {
        [self.delegate sfOrderEncryService:self autoReply: [self encodeDeviceHandle: SFDeviceHandleAutoReply param:@""]];
    }
}

- (void)encry {
    
    NSArray * array = [self decodeOrder:self.orderStr withKey: @"6666666666"];

    if (self.delegate) {
        // 回调数据
        [self.delegate sfOrderEncryService:self didEncrydDeviceInfo:array[0] orderType:[self currentHandle:array[1]] deviceState:array[2]];
        // 是否发送结束
        [self.delegate sfOrderEncryService:self isEnd:isEnd];
    }
}

- (NSArray *)decodeOrder:(NSString *)order withKey:(NSString *)key {
    
    NSData * msgData  = [[NSData alloc]initWithBase64EncodedString:order options:NSDataBase64DecodingIgnoreUnknownCharacters];
    Byte   * msgBytes = (Byte *)[msgData bytes];
    
    NSData * keyData  = [key dataUsingEncoding:NSUTF8StringEncoding];
    Byte   * keyBytes = (Byte *)[keyData bytes];
    
    for (long i       = 0; i < msgData.length; i++) {
        msgBytes[i]   = msgBytes[i] ^ keyBytes[i % keyData.length];
    }
    
    NSMutableArray * dataArr = [NSMutableArray array];
    for (int i = 0; i < msgData.length; i ++) {
        [dataArr addObject:[NSString stringWithFormat:@"%d",msgBytes[i]]];
    }
    
    //解密失败
    if (dataArr.count == 0) {
        return nil;
    }
    
    //设置数据包的header
    [self setPacketHeader:dataArr];
    return [self V2DeviceInfoAndStateWithArray: dataArr];
}

// 设置数据包的Header
- (void)setPacketHeader:(NSArray *)dataArr{
    packetHeaderArr = [NSMutableArray array];
    //header为设备类型，控制类型，协议版本，编号长度，设备编号，固件版本和硬件版本构成
    //需要根据编号长度设置dataArr[3]，前三位是固定的
    //长度控制为 3 + 1 + [dataArr[3] intValue] + 2
    //(设备类型，控制类型，协议版本) + (编号长度) +（设备编号）+（固件版本和硬件版本）
    packetHeaderLength = (int)(3 + 1 + [dataArr[3] intValue] + 2);
    for (int i = 0; i < packetHeaderLength; i ++) {
        [packetHeaderArr addObject:dataArr[i]];
    }
}

- (NSArray *)V2DeviceInfoAndStateWithArray:(NSArray *)dataArr{
    
    NSMutableArray * dataArrCopy = [dataArr mutableCopy];
    
    //保存设备信息
    NSMutableArray * infoArr = [NSMutableArray array];
    
    //保存命令模式 commandKey
    NSMutableArray * commandKeyArr = [NSMutableArray array];
    
    //保存keyValue，还需要进一步解析
    NSMutableArray * keyValueArr = [NSMutableArray array];
    
    
    //前三位分别表示：设备类型(1.人井)、控制类型（1.可控）、协议版本，都是一位，直接添加到infoArr
    //    [infoArr addObjectsFromArray:[dataArr subarrayWithRange:NSMakeRange(0, 3)]];
    //    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 3)];
    
    //设备类型
    deviceType = dataArrCopy[0];
    [infoArr addObject:[self deviceType:dataArrCopy[0]]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    //控制类型
    [infoArr addObject:[self controlType:dataArrCopy[0]]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    //协议版本
    [infoArr addObject:dataArrCopy[0]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    //设备编号长度
    int serialNumberLength = [dataArrCopy[0] intValue];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    //设备编号
    [infoArr addObject:[self nameString:[dataArrCopy subarrayWithRange:NSMakeRange(0, serialNumberLength)]]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, serialNumberLength)];
    
    //固件版本
    [infoArr addObject:dataArrCopy[0]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    //硬件版本
    [infoArr addObject:dataArrCopy[0]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    // Command && Key
    [commandKeyArr addObjectsFromArray:[dataArrCopy subarrayWithRange:NSMakeRange(0, 2)]];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    // key_length
    int keyLength = [dataArrCopy[0] intValue];
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, 1)];
    
    // key_value
    for (int i = 0; i < keyLength; i ++) {
        [keyValueArr addObject:dataArrCopy[i]];
    }
    
    [dataArrCopy removeObjectsInRange:NSMakeRange(0, keyLength)];
    
    // 如果是平衡设备, 没有扩展字段
    // 其他可能存在扩展字段
    // 拼接扩展字段
    if (![deviceType isEqualToString:@"7"]) {
        [keyValueArr addObjectsFromArray:dataArrCopy];
    }
    
    return @[@[@[@"设备类型", infoArr[0]],
               @[@"控制类型", infoArr[1]],
               @[@"协议版本", infoArr[2]],
               @[@"设备编码", infoArr[3]],
               @[@"固件版本", infoArr[4]],
               @[@"硬件版本", infoArr[5]]], commandKeyArr, [self deCodeKeyValueArr:keyValueArr withCommandKey:commandKeyArr]];
}


- (SFDeviceHandle)currentHandle:(NSArray<NSString *> *)commandKeyArr {
    
    NSString * commandKey = [commandKeyArr componentsJoinedByString:@""];
    
    if ([commandKey isEqualToString:@"31"]) {
        return SFDeviceHandleOpen;
    } else if ([commandKey isEqualToString:@"47"]) {
        return SFDeviceHandleAutoReply;
    } else if ([commandKey isEqualToString:@"48"]) {
        return SFDeviceHandleQueryIP;
    } else if ([commandKey isEqualToString:@"49"]) {
        return SFDeviceHandleQueryBalanceParam;
    } else if ([commandKey isEqualToString:@"11"]) {
        return SFDeviceHandleConfigTime;
    } else if ([commandKey isEqualToString:@"21"]) {
        return SFDeviceHandleConfigBlueToothName;
    } else if ([commandKey isEqualToString:@"22"]) {
        return SFDeviceHandleConfigHardwareID;
    } else if ([commandKey isEqualToString:@"18"]) {
        return SFDeviceHandleInitBalanceAngle;
    } else if ([commandKey isEqualToString:@"33"]) {
        return SFDeviceHandleReStart;
    } else if ([commandKey isEqualToString:@"15"]) {
        return SFDeviceHandleConfigUploadTimeSep;
    } else if ([commandKey isEqualToString:@"16"]) {
        return SFDeviceHandleConfigBlueToothWaitTimeSep;
    } else if ([commandKey isEqualToString:@"12"]) {
        return SFDeviceHandleConfigIP;
    } else if ([commandKey isEqualToString:@"17"]) {
        return SFDeviceHandleConfigBalanceParam;
    }
    else {
        NSLog(@"commandeKey: %@", commandKey);
        return SFDeviceHandleReStart;
    }
}

/**
 *  解析KeyValue
 *
 *  @param keyValueArr keyValueArr description 有可能是空的
 *  @param comandKey   根据commandKey输出不同Value
 *
 *  @return keyValue
 */
- (NSArray *)deCodeKeyValueArr:(NSArray *)keyValueArr withCommandKey:(NSArray *)comandKey{
    NSArray * keyValueCopy = [NSArray array];
    
    // command
    switch ([comandKey.firstObject integerValue]) {
            
        case 1:     // 设置命令
            switch ([comandKey.lastObject integerValue]) {      // Key
                case 1:                 // 时间设置
                    break;
                case 2:                 // 中心IP设置
                    break;
                case 3:                 // 中心号码设置
                    break;
                case 4:                 // 驱动时间设置
                    break;
                case 5:                 // 定时上报时间间隔设置
                    break;
                case 6:                 // 蓝牙等待时间设置
                    break;
                default:
                    break;
            }
            break;
        case 2:     // 绑定命令
            switch ([comandKey.lastObject integerValue]) {
                case 1:                 // 蓝牙名称、井号
                    break;
                case 2:                 // 设备ID
                    break;
                case 3:                 // 密钥更改
                    break;
                default:
                    break;
            }
            break;
        case 3:     // 控制命令
            switch ([comandKey.lastObject integerValue]) {
                case 1:                 // 开锁
                    keyValueCopy = [keyValueArr copy];
                    break;
                case 2:                 // 关锁
                    break;
                case 3:                 // 重启设备
                    break;
                case 4:                 // 重启蓝牙
                    break;
                case 5:                 // 关闭连接
                    break;
                default:
                    break;
            }
            break;
        case 4:     // 查询命令
            switch ([comandKey.lastObject integerValue]) {
                case 1:                 // 查询当前状态
                    break;
                case 2:                 // 井号
                    break;
                case 3:                 // 锁号
                    break;
                case 4:                 // 基站信息
                    break;
                case 5:                 // IMSI 手机卡编号
                    break;
                case 6:                 // 历史手机信号，当前手机信号
                    break;
                case 7:                 // 主动上报
                    
                    if ([deviceType isEqualToString:@"7"]) {
                        keyValueCopy = [self decode0aKeyValueArr:keyValueArr];
                    } else {
                        keyValueCopy = [self deviceStateWithKeyValue:keyValueArr];
                    }
                    break;
                case 8:
                    keyValueCopy = [self deviceIP:keyValueArr];
                    break;
                case 9:
                    keyValueCopy = [self balanceParams:keyValueArr];
                default:
                    break;
            }
            break;
        case 5:     // 调试命令
            switch ([comandKey.lastObject integerValue]) {
                case 1:                 // 通讯模块IP调试
                    break;
                case 2:                 // 通讯模块短信调试
                    break;
                case 3:                 // 驱动调试
                    break;
                case 4:                 // 电压调试
                    break;
                case 5:                 // 开关量调试
                    break;
                case 6:                 // 温湿度调试
                    break;
                case 7:                 // 读取日志
                    break;
                case 8:                 // Echo模式
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    
    return keyValueCopy;
}

// MARK: - 平衡人井设备状态
// =================================================
//                     平衡人井设备状态所用
// =================================================
// 返回阀值 key_value 也就是主动上报的内容
- (NSArray *)decode0aKeyValueArr:(NSArray *)keyValue {
    
    NSMutableArray * keyValueCopy = [keyValue mutableCopy];
    NSMutableArray * keyValueArr = [NSMutableArray array];
    
    //X轴加速度最大值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //Y轴加速度最大值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //Z轴加速度最大值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //X轴加速度阀值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //Y轴加速度阀值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //Z轴加速度阀值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //X轴倾斜最大值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //Y轴倾斜最大值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //Z轴倾斜最大值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //X轴倾斜阀值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //Y轴倾斜阀值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //Z轴倾斜阀值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //X轴倾斜角度初始值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //Y轴倾斜角度初始值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    //
    //    //Z轴倾斜角度初始值
    //    [keyValueArr addObject:keyValueCopy[0]];
    //    [keyValueCopy removeObjectAtIndex:0];
    
    [keyValueArr addObjectsFromArray: [keyValueCopy subarrayWithRange: NSMakeRange(0, 9)]];
    [keyValueCopy removeObjectsInRange: NSMakeRange(0, 9)];
    
    //唤醒状态
    [keyValueArr addObject:[self v2SwitchState:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //状态原因
    [keyValueArr addObject:[self stateReason:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //状态产生的时间
    [keyValueArr addObject:[self stateTime:[keyValueCopy subarrayWithRange:NSMakeRange(0, 6)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 6)];
    
    //信号
    [keyValueArr addObject:keyValueCopy[0]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //电池
    [keyValueArr addObject:[self electricity:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //通讯序列号
    [keyValueArr addObject:[self messageNumber:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //是否发送结束
    [keyValueArr addObject:[self isEnd:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //设备名称长度
    int nameLangth = [keyValueCopy[0] intValue];
    
    //设备名称
    [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(1, nameLangth)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, nameLangth + 1)];
    
   return @[@[@"X轴加速度最大值", keyValueArr[0]],
          @[@"Y轴加速度最大值", keyValueArr[1]],
          @[@"Z轴加速度最大值", keyValueArr[2]],
          @[@"X轴加速度阀值", keyValueArr[3]],
          @[@"Y轴加速度阀值", keyValueArr[4]],
          @[@"Z轴加速度阀值", keyValueArr[5]],
          @[@"X轴倾斜最大值", keyValueArr[6]],
          @[@"Y轴倾斜最大值", keyValueArr[7]],
          @[@"Z轴倾斜最大值", keyValueArr[8]],
          @[@"X轴倾斜阀值", keyValueArr[9]],
          @[@"Y轴倾斜阀值", keyValueArr[10]],
          @[@"Z轴倾斜阀值", keyValueArr[11]],
          @[@"X轴倾斜角度初始值", keyValueArr[12]],
          @[@"Y轴倾斜角度初始值", keyValueArr[13]],
          @[@"Z轴倾斜角度初始值", keyValueArr[14]],
          @[@"唤醒状态", keyValueArr[15]],
          @[@"状态原因", keyValueArr[16]],
          @[@"状态生成时间", keyValueArr[17]],
          @[@"信号", keyValueArr[18]],
          @[@"电池", keyValueArr[19]],
          @[@"通讯序列号", keyValueArr[20]],
          @[@"是否结束", keyValueArr[21]],
          @[@"硬件编码", keyValueArr[22]]];
}

/**
 command = 4 key = 9
 平衡参数
 */
- (NSArray *)balanceParams:(NSArray *)keyValue {
    NSMutableArray * keyValueCopy = [keyValue mutableCopy];
    NSMutableArray * keyValueArr = [NSMutableArray array];
    
    //X阀值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //Y阀值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //Z阀值
    [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //X角度
    [keyValueArr addObject:keyValueCopy[0]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //Y角度
    [keyValueArr addObject:keyValueCopy[0]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //Z角度
    [keyValueArr addObject:keyValueCopy[0]];
    [keyValueCopy removeObjectAtIndex:0];
    
    return @[@[@"X轴阀值", keyValueArr[0]],
             @[@"Y轴阀值", keyValueArr[1]],
             @[@"Z轴阀值", keyValueArr[2]],
             @[@"X角度", keyValueArr[3]],
             @[@"Y角度", keyValueArr[4]],
             @[@"Z角度",keyValueArr[5]]];
}

/**
 *  command = 4 key = 8
 *
 *  @param keyValue keyValue description
 *
 *  @return keyValue @[IP]
 */
- (NSArray *)deviceIP:(NSArray *)keyValue{
    
    if (keyValue.count != 7) {
        return nil;
    }
    
    NSString * portNum = [NSString stringWithFormat:@"%d",[keyValue[5] intValue] * 256 + [keyValue[6] intValue]];
    NSArray * ipNumArr = [keyValue subarrayWithRange:NSMakeRange(1, 4)];
    NSString * ipString = [ipNumArr componentsJoinedByString:@"."];
    return @[[NSString stringWithFormat:@"%@:%@",ipString, portNum]];
}

/**
 *  command = 4 key = 7
 *
 *  @param keyValue keyValue description
 *
 *  @return keyValue @[@[标题]，@[数据]]
 */
- (NSArray *)deviceStateWithKeyValue:(NSArray *)keyValue{
    
    NSMutableArray * keyValueCopy = [keyValue mutableCopy];
    NSMutableArray * keyValueArr = [NSMutableArray array];
    
    //锁柱状态
    [keyValueArr addObject:[self willCapState:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //压板状态
    [keyValueArr addObject:[self willCapState:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //唤醒状态
    [keyValueArr addObject:[self v2SwitchState:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //状态原因
    [keyValueArr addObject:[self stateReason:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //状态产生的时间
    [keyValueArr addObject:[self stateTime:[keyValueCopy subarrayWithRange:NSMakeRange(0, 6)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 6)];
    
    //信号
    [keyValueArr addObject:keyValueCopy[0]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //电池
    [keyValueArr addObject:[self electricity:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //湿度，温度
    [keyValueArr addObjectsFromArray:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    //通讯序列号
    [keyValueArr addObject:[self messageNumber:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
    
    //是否发送结束
    [keyValueArr addObject:[self isEnd:keyValueCopy[0]]];
    [keyValueCopy removeObjectAtIndex:0];
    
    //设备名称长度
    int nameLangth = [keyValueCopy[0] intValue];
    
    //设备名称
    [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(1, nameLangth)]]];
    [keyValueCopy removeObjectsInRange:NSMakeRange(0, nameLangth + 1)];
    
    NSMutableArray *titleArr = [@[@"锁柱状态",
                                  @"压板开关",
                                  @"唤醒状态",
                                  @"状态原因",
                                  @"状态生成时间",
                                  @"信号",
                                  @"电池",
                                  @"温度",
                                  @"湿度",
                                  @"通讯序列号",
                                  @"是否结束",
                                  @"硬件编码"] mutableCopy];
    
    // 还有扩展字段
    if (keyValueCopy.count > 0) {
        // 扩展字段的长度
        int extLength = [keyValueCopy[0] intValue];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 1)];
        // 表明还有除了平衡参数之外的扩展字段
        if (extLength > 12) {
            // fnc长度
            int fncLength = [keyValueCopy[0] intValue];
            [keyValueCopy removeObjectAtIndex:0];
            [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, fncLength)]]];
            [keyValueCopy removeObjectsInRange:NSMakeRange(0, fncLength)];
            
            // pci
            int pciLength = [keyValueCopy[0] intValue];
            [keyValueCopy removeObjectAtIndex:0];
            [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, pciLength)]]];
            [keyValueCopy removeObjectsInRange:NSMakeRange(0, pciLength)];
            
            // cid
            int cidLength = [keyValueCopy[0] intValue];
            [keyValueCopy removeObjectAtIndex:0];
            [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, cidLength)]]];
            [keyValueCopy removeObjectsInRange:NSMakeRange(0, cidLength)];
            
            // rsrp
            int rsrpLength = [keyValueCopy[0] intValue];
            [keyValueCopy removeObjectAtIndex:0];
            [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, rsrpLength)]]];
            [keyValueCopy removeObjectsInRange:NSMakeRange(0, rsrpLength)];
            
            // sinr
            int sinrLength = [keyValueCopy[0] intValue];
            [keyValueCopy removeObjectAtIndex:0];
            [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, sinrLength)]]];
            [keyValueCopy removeObjectsInRange:NSMakeRange(0, sinrLength)];
            
            // ecl
            int eclLength = [keyValueCopy[0] intValue];
            [keyValueCopy removeObjectAtIndex:0];
            [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, eclLength)]]];
            [keyValueCopy removeObjectsInRange:NSMakeRange(0, eclLength)];
            
            [titleArr addObjectsFromArray:@[@"NB频点",
                                            @"小区物理ID",
                                            @"小区ID",
                                            @"信号接收功率",
                                            @"信噪比",
                                            @"覆盖范围"]];
        }
        
        //X轴加速度变化最大值
        [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
        
        //Y轴加速度变化最大值
        [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
        
        //Z轴加速度变化最大值
        [keyValueArr addObject:[self blanceNum:[keyValueCopy subarrayWithRange:NSMakeRange(0, 2)]]];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 2)];
        
        [keyValueArr addObjectsFromArray:[keyValueCopy subarrayWithRange:NSMakeRange(0, 6)]];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 6)];
        
        [titleArr addObjectsFromArray:@[@"X轴加速度最大值",
                                        @"Y轴加速度最大值",
                                        @"Z轴加速度最大值",
                                        @"X轴倾斜最大值",
                                        @"Y轴倾斜最大值",
                                        @"Z轴倾斜最大值",
                                        @"X轴倾斜角度初始值",
                                        @"Y轴倾斜角度初始值",
                                        @"Z轴倾斜角度初始值"]];
    }
    
    // IMEI + IMSI  共30位长度,分别15位
    if (keyValueCopy.count > 30) {
        // IMEI
        [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, 15)]]];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 15)];
        
        // IMSI
        [keyValueArr addObject:[self nameString:[keyValueCopy subarrayWithRange:NSMakeRange(0, 15)]]];
        [keyValueCopy removeObjectsInRange:NSMakeRange(0, 15)];
        
        [titleArr addObjectsFromArray:@[@"IMEI",
                                        @"IMSI"]];
    }
        
    NSMutableArray * deviceState = [NSMutableArray array];
    for (int i = 0 ; i < titleArr.count; i ++ ) {
        [deviceState addObject: @[titleArr[i], keyValueArr[i]]];
    }
    
    return deviceState;
}

// 平衡参数
- (NSString *)blanceNum:(NSArray <NSString *> *)numberArr {
    if ([numberArr count] == 2) {
        return [NSString stringWithFormat:@"%d",[numberArr[0] intValue] * 256 + [numberArr[1] intValue]];
    }
    return @"0";
}

//电池
- (NSString *)electricity:(NSString *)electricity{
    if (electricity.length > 1) {
        int a = [electricity intValue] / 10;
        int b = [electricity intValue] % 10;
        return [NSString stringWithFormat:@"%d.%dv",a,b];
    }else {
        return [NSString stringWithFormat:@"%@.v",electricity];
    }
}

// 设备类型
- (NSString *)deviceType:(NSString *)type{
    if ([type isEqualToString:@"1"]) {
        return @"蓝牙流量人井";
    }else if ([type isEqualToString:@"5"]) {
        return @"一体化井盖";
    }else if ([type isEqualToString:@"7"]){
        return @"平衡设备";
    }else {
        return @"其他类型";
    }
}

// 控制类型
- (NSString *)controlType:(NSString *)type{
    return [type isEqualToString:@"1"] ? @"可控" : @"不可控";
}


//通讯序列号
- (NSString *)messageNumber:(NSArray *)state{
    if ([state[0] intValue] == 0) {
        return state[1];
    }else{
        return [state componentsJoinedByString:@""];
    }
}

//设备名称
- (NSString *)nameString:(NSArray *)nameArr{
    NSMutableString * serialNumber = [NSMutableString string];
    for (NSString * ascStr in nameArr) {
        int ascNum = [ascStr intValue];
        [serialNumber appendString:[NSString stringWithFormat:@"%c",(char)ascNum]];
    }
    return [serialNumber copy];
}

//是否发送结束
- (NSString *)isEnd:(NSString *)state{
    isEnd = [state isEqualToString: @"0"];
    return [state isEqualToString:@"0"] ? @"发送结束" : @"未发送结束";
}

//状态产生的时间
- (NSString *)stateTime:(NSArray *)time{
    if (time.count == 6) {
        return [NSString stringWithFormat:@"20%@-%.2d-%.2d %.2d:%.2d:%.2d",time[0],[time[1] intValue],[time[2] intValue],[time[3] intValue],[time[4] intValue],[time[5] intValue]];
    }
    return [time componentsJoinedByString:@","];
}

//状态原因
- (NSString *)stateReason:(NSString *)state{
    if ([state isEqualToString:@"0"]) {
        return @"设备产生的数据";
    }else if ([state isEqualToString:@"1"]){
        return @"查询的数据";
    }else{
        return @"定时数据";
    }
}

//内井盖状态，外井盖状态
- (NSString *)willCapState:(NSString *)state{
    if ([state isEqualToString:@"1"]) {
        return @"开启";
    }else if ([state isEqualToString:@"2"]){
        return @"关闭";
    }else{
        return @"非法开启";
    }
}

//唤醒状态
- (NSString *)v2SwitchState:(NSString *)state{
    return [state isEqualToString:@"1"] ? @"唤醒" : @"未唤醒";
}

- (NSString *)reportType:(NSString *)type{
    return [type isEqualToString:@"r"] ? @"触发上报" : @"查询上报";
}

- (NSString *)switchState:(NSString *)state{
    return [state isEqualToString:@"v"] ? @"唤醒开关有效" : @"唤醒开关无效";
}

- (NSString *)wellState:(NSString *)state{
    if ([state isEqualToString:@"o"]) {
        return @"开启";
    }else if ([state isEqualToString:@"c"]){
        return @"关闭";
    }else{
        return @"非法开启";
    }
}

- (NSString *)weiGouState:(NSString *)state{
    if ([state isEqualToString:@"o"]) {
        return @"开启";
    }else if ([state isEqualToString:@"c"]){
        return @"关闭";
    }else{
        return @"非法开启";
    }
}

- (NSString *)hallState:(NSString *)state{
    return [state isEqualToString:@"o"] ? @"开启" : @"关闭";
}

- (NSString *)dataID:(NSString *)state{
    if ([state isEqualToString:@"t"]) {
        return @"上行命令模式";
    }else{
        return @"下行命令模式";
    }
}

- (NSData *)encodeArray:(NSArray *)sourceArr{
    
    NSString * key = @"6666666666";
    
    // 连续像设备发命令的时候Header需要重新设置
    [packetHeaderArr removeObjectsInRange:NSMakeRange(packetHeaderLength, packetHeaderArr.count - packetHeaderLength)];
    
    // 拼接数据包
    [packetHeaderArr addObjectsFromArray:sourceArr];
    
    // packet的chechSum，由于设备没有添加校验机制，暂用0，0
    [packetHeaderArr addObjectsFromArray:@[@"0", @"0"]];
    
    
    Byte * byteData = (Byte*)malloc(packetHeaderArr.count);
    
    for (int i = 0; i < packetHeaderArr.count; i ++) {
        byteData[i] = (Byte)[packetHeaderArr[i] intValue];
    }
    
    NSData * msgData = [NSData dataWithBytes:byteData length:packetHeaderArr.count];
    NSData * keyData  = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    Byte   * keyBytes = (Byte *)[keyData bytes];
    Byte   * msgBytes = (Byte *)[msgData bytes];
    
    // 异或加密
    for (long i       = 0; i < msgData.length; i++) {
        msgBytes[i]   = msgBytes[i] ^ keyBytes[i % keyData.length];
    }
    
    // Base64加密
    NSString * dataStr = [(NSData *)[NSData dataWithBytes:msgBytes length:msgData.length] base64EncodedStringWithOptions:0];
    
    NSString * decodeStr = [NSString stringWithFormat:@"%.3lu%@", dataStr.length, dataStr];
    return [decodeStr dataUsingEncoding:NSUTF8StringEncoding];
}

- (NSData *)encodeDeviceHandle:(SFDeviceHandle)handle param:(id)param {
    
    switch (handle) {
            
        case SFDeviceHandleQueryIP: {
            return [self encodeArray:@[@"4", @"8", @"1", @"0"]];
        }
            
        case SFDeviceHandleQueryState: {
            return [self encodeArray:@[@"4", @"1", @"1", @"0"]];
        }
            
        case SFDeviceHandleAutoReply: {
            return [self encodeArray:@[@"4", @"7", @"1", @"1"]];
        }
            
        case SFDeviceHandleQueryBalanceParam: {
            return [self encodeArray:@[@"4", @"9", @"1", @"0"]];
        }
            
        case SFDeviceHandleInitBalanceAngle: {
            return [self encodeArray:@[@"1", @"8", @"1", @"0"]];
        }
            
        case SFDeviceHandleOpen: {
            return [self encodeArray:@[@"3", @"1", @"1", @"0"]];
        }
            
        case SFDeviceHandleReStart: {
            return [self encodeArray:@[@"3", @"3", @"1", @"0"]];
        }
            
        case SFDeviceHandleConfigBlueToothWaitTimeSep: {
            NSString * timeStp = (NSString *)param;
            if (timeStp == nil || [timeStp floatValue] == 0 ) {
                NSLog(@"请输入正确的蓝牙等待时间");
                return nil;
            }
            NSMutableArray * timeSepArr = [NSMutableArray arrayWithArray: @[@"1", @"6"]];
            [timeSepArr addObject: [NSString stringWithFormat:@"%lu", timeStp.length + 1]];
            [timeSepArr addObject: [NSString stringWithFormat:@"%lu", timeStp.length + 1]];
            const char *cStr = [timeStp cStringUsingEncoding: NSASCIIStringEncoding];
            for (int index = 0; index < timeStp.length; index ++) {
                [timeSepArr addObject: [NSString stringWithFormat:@"%d", cStr[index]]];
            }
            return [self encodeArray:[timeSepArr copy]];
        }
            
        case SFDeviceHandleConfigUploadTimeSep: {
            NSString * timeStp = (NSString *)param;
            if (timeStp == nil || [timeStp floatValue] == 0 ) {
                NSLog(@"请输入正确的主动上报时间间隔");
                return nil;
            }
            NSMutableArray * timeSepArr = [NSMutableArray arrayWithArray: @[@"1", @"5"]];
            [timeSepArr addObject: [NSString stringWithFormat:@"%lu", timeStp.length + 1]];
            [timeSepArr addObject: [NSString stringWithFormat:@"%lu", timeStp.length + 1]];
            const char *cStr = [timeStp cStringUsingEncoding: NSASCIIStringEncoding];
            for (int index = 0; index < timeStp.length; index ++) {
                [timeSepArr addObject: [NSString stringWithFormat:@"%d", cStr[index]]];
            }
            return [self encodeArray:[timeSepArr copy]];
        }
            
        case SFDeviceHandleConfigBalanceParam: {
            
            NSArray * balanceArr = (NSArray<NSString *> *)param;
            if (balanceArr == nil || balanceArr.count != 6) {
                NSLog(@"请输入正确的平衡参数");
                return nil;
            }
            NSMutableArray * configArr = [NSMutableArray arrayWithArray: @[@"1", @"7", @"9"]];
            
            for (int index = 0; index < balanceArr.count; index ++) {
                if (index < 3) {
                    int itemInt = [balanceArr[index] intValue];
                    [configArr addObject: [NSString stringWithFormat:@"%d", itemInt / 256]];
                    [configArr addObject: [NSString stringWithFormat:@"%d", itemInt % 256]];
                } else {
                    [configArr addObject: balanceArr[index]];
                }
            }
            return [self encodeArray: [configArr copy]];
        }
            
        case SFDeviceHandleConfigTime: {
            NSDate * date = (NSDate *)param;
            if (date == nil) {
                NSLog(@"请输入正确的日期格式");
                return nil;
            }
            NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
            formatter.dateFormat = @"yy MM dd HH mm ss";
            NSString * dateString = [formatter stringFromDate:date];
            NSMutableArray * timeArr = [NSMutableArray arrayWithArray:@[@"1", @"1", @"6"]];
            [timeArr addObjectsFromArray:[dateString componentsSeparatedByString:@" "]];
            return [self encodeArray: [timeArr copy]];
        }
            
        case SFDeviceHandleConfigIP: {
            NSMutableArray * ipArr = [(NSArray<NSString *> *)param mutableCopy];
            if (ipArr == nil || ipArr.count != 5 ) {
                NSLog(@"请输入正确的IP参数");
                return nil;
            }
            
            // 设置端口
            NSString * port = [ipArr lastObject];
            [ipArr removeLastObject];
            [ipArr addObjectsFromArray:@[[NSString stringWithFormat:@"%d",[port intValue] / 256], [NSString stringWithFormat:@"%d",[port intValue] % 256]]];
            NSMutableArray * ipParam = [NSMutableArray arrayWithArray:@[@"1", @"2", @"7", @"170"]];
            [ipParam addObjectsFromArray:ipArr];
            return [self encodeArray: [ipParam copy]];
        }
            
        case SFDeviceHandleConfigBlueToothName: {
            NSString * blueName = (NSString *)param;
            if (blueName == nil || blueName.length == 0) {
                NSLog(@"请输入正确的蓝牙名称");
                return nil;
            }
            
            NSMutableArray * nameArr = [NSMutableArray arrayWithArray: @[@"2", @"1"]];
            [nameArr addObject:[NSString stringWithFormat:@"%ld", blueName.length + 1]];
            [nameArr addObject:[NSString stringWithFormat:@"%ld", blueName.length]];
            const char *cStr = [blueName cStringUsingEncoding: NSASCIIStringEncoding];
            for (int index = 0; index < blueName.length; index ++) {
                [nameArr addObject: [NSString stringWithFormat:@"%d", cStr[index]]];
            }
            return [self encodeArray:[nameArr copy]];
        }
            
        case SFDeviceHandleConfigHardwareID: {
            NSString * idString = (NSString *)param;
            if (idString == nil || idString.length == 0) {
                NSLog(@"请输入正确的硬件编码");
                return nil;
            }
            
            NSMutableArray * idArr = [NSMutableArray arrayWithArray: @[@"2", @"2"]];
            [idArr addObject:[NSString stringWithFormat:@"%ld", idString.length + 1]];
            [idArr addObject:[NSString stringWithFormat:@"%ld", idString.length]];
            
            const char *cStr = [idString cStringUsingEncoding: NSASCIIStringEncoding];
            for (int index = 0; index < idString.length; index ++) {
                [idArr addObject: [NSString stringWithFormat:@"%d", cStr[index]]];
            }
            return [self encodeArray:[idArr copy]];
        }
    }
    return NSData.data;
}


@end
